package com.visionblue.business.ship.page

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.visionblue.business.ship.base.ViewState
import com.visionblue.business.ship.ext.SingleLiveEvent
import com.visionblue.business.ship.model.Results
import com.visionblue.business.ship.model.bean.response.NotificationBean
import com.visionblue.business.ship.model.bean.response.ShipInfo
import com.visionblue.business.ship.model.enums.ApplicationRecordStatusEnum
import com.visionblue.business.ship.model.repository.DeviceInfoRepository
import com.visionblue.business.ship.model.repository.db.RecordAndOrderRelation
import com.visionblue.business.ship.page.applications.ApplicationsRepository
import com.visionblue.business.ship.page.applications.AbsApplicationsViewModel
import com.visionblue.business.ship.util.tickerFlow
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch

/**
 * @author: xlh
 * @date: 2020-05-21 2:21 PM
 * @desc:
 */
class MainViewModel(
    private val mainRepository: MainRepository,
    private val deviceInfoRepository: DeviceInfoRepository,
    applicationsRepo: ApplicationsRepository
) : AbsApplicationsViewModel(applicationsRepo) {

    var scheduledJob: Job? = null

    // 宿主船信息state
    val hostShipInfoState = MutableLiveData<ViewState<ShipInfo>>()

    // 通知state
    val notificationState = MutableLiveData<ViewState<NotificationBean>>()

    // 接驳船接收/拒绝申报 结果
    val operateTaskEvent = SingleLiveEvent<ViewState<Any>>()

    val cachedOrderLiveData = MutableLiveData<List<RecordAndOrderRelation>>()

    fun loadDataScheduled() {

        val tickerFlow = tickerFlow(15 * 1000)

        scheduledJob?.cancel()
        scheduledJob = viewModelScope.launch {
            tickerFlow.collect {
                getNotification()
            }
        }
        val tickerFlow1 = tickerFlow(600000* 1000)
        viewModelScope.launch {
            tickerFlow1.collect {
                getHostShipInfo()
            }
        }
    }

    fun cancelSchedule() {
        scheduledJob?.cancel()
        scheduledJob = null
    }

    fun setApplicationRead(id: String?) {
        if (id == null) {
            return
        }

        viewModelScope.launch {
            mainRepository.putApplicationView(id)
            getNotification()
        }
    }

    fun declineTask(id: String?) {
        operateTask(id, 2)
    }

    fun receiveTask(id: String?) {
        operateTask(id, 1)
    }

    fun loadCachedOrderInfo() {
        viewModelScope.launch {
            val cachedOrders = mainRepository.getCachedOrders(deviceInfoRepository.sn)
            cachedOrderLiveData.value = cachedOrders
        }
    }

    fun isDeviceRegistry(): Boolean = deviceInfoRepository.sn.isNotEmpty()

    fun refreshHostShipInfo() {
        viewModelScope.launch {
            getHostShipInfo()
        }
    }

    override fun getApplicationStatus(): List<Int> {
        return listOf(
            ApplicationRecordStatusEnum.PENDING.status,
            ApplicationRecordStatusEnum.PROCESSING.status
        )
    }
//    /**
//     * 是否有接收中的任务
//     */
//    fun hasProcessing(): Boolean {
//        val notificationBean = notificationState.value?.data
//        return notificationBean != null && notificationBean.processing > 0
//    }

    //--------------private ----------------------

    private fun operateTask(id: String?, opCode: Int) {
        if (id == null) {
            return
        }

        viewModelScope.launch {
            checkState(operateTaskEvent, Results.Loading)
            checkState(operateTaskEvent, mainRepository.putApplicationStatus(id, opCode))
        }
    }

    private suspend fun getHostShipInfo() {
        checkState(hostShipInfoState, mainRepository.getHostShipInfo())
    }

    private suspend fun getNotification() {
        checkState(notificationState, mainRepository.getNotification())
    }

    fun cacheDeviceInfo(shipName: String?) {
        if (shipName == null) return
        deviceInfoRepository.shipName = shipName
    }

}